﻿using HarfBuzzSharp;
using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Runtime;
using LightCAD.Three;
using netDxf.Entities;
using SkiaSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using LightCAD.MathLib;
using Avalonia.Controls;
using System.Runtime.Intrinsics.X86;
using Avalonia.Input;
using Avalonia;
using Avalonia.Controls.Shapes;
using Microsoft.CodeAnalysis.Emit;
using static LightCAD.Core.Elements.LcPolyLine;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Net;

namespace LightCAD.Drawing.Actions
{
    public class ExtendAction : ITransformDrawer
    {
        public static string CommandName;
        public static LcCreateMethod[] CreateMethods;
        protected DocumentRuntime docRt;
        protected ViewportRuntime vportRt;
        protected IDocumentEditor docEditor;
        protected ICommandControl commandCtrl;
        private Vector2 basePoint;

        static ExtendAction()
        {
            CommandName = "EXTEND";
            CreateMethods = new LcCreateMethod[1];
            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "EX",
                Description = "EXTEND",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{ Name="Step0", Options="EXTEND 选择对象或<全部选择>:" },
                    new LcCreateStep { Name="Step1", Options= "EXTEND 选择对象:" },
                    new LcCreateStep { Name="Step2", Options= "EXTEND [栏选(F)窗交(C)投影(P)边(E)]:" },
                }
            };
        }

        private PointInputer inputer { get; set; }
        private ElementSetInputer ElementInputers { get; set; }
        private ElementInputer ElementInputer { get; set; }
        private CmdTextInputer CmdTextInputer { get; set; }
        private PointInputer PointInputer { get; set; }
        private List<LcElement> selectedElements;
        private List<LcElement> selectedEXElements;
        public ExtendAction() { }
        public ExtendAction(IDocumentEditor docEditor)
        {
            this.docEditor = docEditor;
            this.docRt = docEditor.DocRt;
            this.vportRt = (docEditor as DrawingEditRuntime).ActiveViewportRt;
            this.commandCtrl = this.vportRt.CommandCtrl;
            this.commandCtrl.WriteInfo("命令 ：EX");
        }



        private LcCreateMethod GetMethod(string method)
        {
            if (method == null) return CreateMethods[0];
            var getted = CreateMethods.FirstOrDefault((m) => m.Name == method);
            if (getted == null)
                return CreateMethods[0];
            else
                return getted;
        }
        public async void ExecCreate(string[] args = null)
        {
            this.StartAction();
            var curMethod = CreateMethods[0];
            this.ElementInputers = new ElementSetInputer(this.docEditor);
            this.CmdTextInputer = new CmdTextInputer(this.docEditor);
            this.PointInputer = new PointInputer(this.docEditor);
        Step0:
            var step0 = curMethod.Steps[0];
            var result0 = await ElementInputers.Execute(step0.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (result0 == null || result0.IsCancelled)
            {
                this.Cancel();
                goto End;
            }
            this.selectedElements = new List<LcElement>();
            this.selectedElements.AddRange((List<LcElement>)result0.ValueX);
            if (selectedElements.Count > 0)
            {
                if (result0.Option != null)
                {
                    goto Step1;
                }
                else
                {
                    goto Step0;
                }
            }
            else
                goto Step0;
            Step1:  //第二步  执行延伸 
            this.vportRt.SetTransformDrawer(this);     //开启渲染
            var step1 = curMethod.Steps[1];
           
            var result1 = await ElementInputers.Execute(step1.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            if (result1 == null || result1.IsCancelled)
            {
                this.Cancel();
                goto End;
            }
            this.selectedEXElements = new List<LcElement>();
            List<LcElement> selects = new List<LcElement>();
            selects.AddRange((List<LcElement>)result1.ValueX);
            foreach (var item in selects)
            {
                if (selectedElements.Contains(item))
                {
                    //selects.Remove(item);
                }
                else
                {
                    this.selectedEXElements.Add(item);
                }
            }
            if (selectedEXElements.Count != null)
            {
                if (result0.Option != null)
                {
                    CreateExtend();
                }
            }
            else
                goto Step1;
            End:
            this.EndAction();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="center"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="a1">线 开始</param>
        /// <param name="a2">线 结束</param>
        /// <returns></returns>
     
        public void CreateExtend()
        {
            if (selectedElements != null)
            {
                foreach (var element1 in selectedElements)
                {
                    foreach (var element2 in selectedEXElements)
                    {
                        if (element2 != null && element2 != element1)
                        {
                            List<Vector2> points = new List<Vector2>();
                            if (element2 is LcPolyLine) //判断第二个元素是不是多段线
                            {
                                ExtendPolyLine(element1, element2, points);
                            }
                            //如果不是多段线
                            else
                            {
                                if(element1 !=null && element2 != null)
                                {
                                    //LcEllipse.matrix3 = this.vportRt.WcsToScr;
                                    //LcEllipse.Scale = this.vportRt.Viewport.Scale;
                                    points = element1.GetCrossVectorByElement(element2);
                                }

                                if (points == null || points.Count == 0)
                                {

                                }
                                else
                                {
                                    if (element2 is LcLine)  //如果第二次选中的是线
                                    {

                                        LcLine line2 = element2 as LcLine;
                                        Vector2 point = new Vector2();
                                        List<Vector2> points2 = new List<Vector2>(); 
                                        List<Vector2> point1s = new List<Vector2>();  //point1s用来存储离直线开始点近得点
                                        List<Vector2> point2s = new List<Vector2>();  //point2s用来存储离直线结束点近得点
                                        
                                        if (points.Count > 0)
                                        {
                                            foreach (var item in points) //判断点是不是在直线的延长线上  如果是  就加入到points2集合中
                                            {
                                             if(item != null)
                                                {
                                                    if (GeoUtils.IsPointOnLineExtension(line2.Start, line2.End, item))
                                                    {
                                                    }
                                                    else
                                                    {
                                                        points2.Add(item);
                                                    }
                                                }
                                            }
                                            foreach(var item1 in points2)
                                            {

                                                double diatance1 = Vector2.Distance(item1, line2.Start);
                                                double diatance2 = Vector2.Distance(item1, line2.End);
                                                if (diatance1 < diatance2)
                                                {
                                                    point1s.Add(item1);
                                                }
                                                else
                                                {
                                                    point2s.Add(item1);
                                                }

                                            }
                                        }
                                        var wcsp1 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());//求出移动点，判断移动点与开始点近还是结束点近
                                        double diatance3 = Vector2.Distance(wcsp1, line2.Start);
                                        double diatance4 = Vector2.Distance(wcsp1, line2.End);
                                        
                                        if (diatance3 < diatance4)
                                        {
                                            if (point1s.Count == 0)
                                            {

                                            }
                                            else
                                            {
                                                Vector2 temporaryPoint = point1s[0];
                                                double temporaryDiantance = Vector2.Distance(point1s[0], line2.Start);
                                                foreach (var item in point1s)
                                                {
                                                    double diatance = Vector2.Distance(item, line2.Start);
                                                    if (diatance < temporaryDiantance)
                                                    {
                                                        temporaryDiantance = diatance;
                                                        temporaryPoint = item;
                                                    }
                                                    point = temporaryPoint;
                                                    
                                                }
                                                line2.Set(start: point);
                                            } 
                                        }
                                        else
                                        {
                                            if (point2s.Count == 0)
                                            {

                                            }
                                            else
                                            {
                                                Vector2 temporaryPoint = point2s[0];
                                                double temporaryDiantance = Vector2.Distance(point2s[0], line2.End);
                                                foreach (var item in point2s)
                                                {
                                                    double diatance = Vector2.Distance(item, line2.End);
                                                    if (diatance < temporaryDiantance)
                                                    {
                                                        temporaryDiantance = diatance;
                                                        temporaryPoint = item;
                                                    }
                                                    point = temporaryPoint;
                                                    
                                                }
                                                line2.Set(end: point);
                                            }
                                        }
                                    }
                                    if (element2 is LcArc)  //如果第二个选中的是圆弧
                                    {
                                        Vector2 point = new Vector2();
                                        LcArc lcArc = element2 as LcArc;
                                        Arc2d arc2D = new Arc2d();  //逻辑模型
                                        arc2D.IsClockwise = false;
                                        List<Vector2> point1s = new List<Vector2>();  //point1s用来存储离直线开始点近得点
                                        List<Vector2> point2s = new List<Vector2>();  //point2s用来存储离直线结束点近得点
                                        bool rf;
                                        if (points.Count > 0)
                                        {
                                            List<Vector2> endpoints = new List<Vector2>();
                                            foreach (var item in points)
                                            {
                                                if(item != null )
                                                {
                                                    //&& GeoUtils.IsPointOnArcExtension(arc2D, item)
                                                    if (!Arc2d.PointInArc(item, lcArc.Startp, lcArc.Endp, lcArc.Center))
                                                    {
                                                        endpoints.Add(item);
                                                    }
                                                }

                                            }
                                            foreach (var item in endpoints)
                                            {
                                                if (endpoints.Count == 1)
                                                {
                                                    point1s.Add(item);
                                                    point2s.Add(item);
                                                }
                                                else
                                                {
                                                    double distance1 = Vector2.Distance(item, lcArc.Startp);
                                                    double distance2 = Vector2.Distance(item, lcArc.Endp);
                                                    if (distance1 < distance2)
                                                    {
                                                        point1s.Add(item);
                                                    }
                                                    else
                                                    {
                                                        point2s.Add(item);
                                                    }
                                                }
                                            }
                                        }
                                        var wcsp1 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());
                                        double ds = Vector2.Distance(wcsp1, lcArc.Startp);
                                        double de = Vector2.Distance(wcsp1, lcArc.Endp);
                                        if (ds< de)
                                        {
                                            if (point1s.Count == 0)
                                            {

                                            }
                                            else
                                            {
                                                Vector2 temporaryPoint = point1s[0];
                                                double temporaryDiantance = Vector2.Distance(point1s[0], lcArc.Startp);
                                                foreach (var item in point1s)
                                                {
                                                    double diatance = Vector2.Distance(item, lcArc.Startp);
                                                    if (diatance < temporaryDiantance)
                                                    {
                                                        temporaryDiantance = diatance;
                                                        temporaryPoint = item;
                                                    }
                                                    point = temporaryPoint;

                                                }
                                                lcArc.Set(start: point);
                                            }
                                        }
                                        else
                                        {
                                            if (point2s.Count == 0)
                                            {

                                            }
                                            else
                                            {
                                                Vector2 temporaryPoint = point2s[0];
                                                double temporaryDiantance = Vector2.Distance(point2s[0], lcArc.Endp);
                                                foreach (var item in point2s)
                                                {
                                                    double diatance = Vector2.Distance(item, lcArc.Endp);
                                                    if (diatance < temporaryDiantance)
                                                    {
                                                        temporaryDiantance = diatance;
                                                        temporaryPoint = item;
                                                    }
                                                    point = temporaryPoint;

                                                }
                                                lcArc.Set(end: point);
                                            }
                                        }
                                    }
                                    
                                }
                            }
                        }
                    }
                }
            }
        }
        //public virtual void DrawExtend(SKCanvas canvas)
        //{
        //    CreateExtend();
        //}

        public void Cancel()
        {
            this.DetachEvents();
            //TODO:
            //this.EndAction();
        }
        public void StartAction()
        {
            if (vportRt.CheckStatus(ViewportStatus.InAction))
            {
                vportRt.CancelCurrentAction();
            }
            vportRt.SetStatus(ViewportStatus.InAction);
            this.vportRt.CommandCenter.InAction = true;
        }
        public void EndAction()
        {
            this.vportRt.SetTransformDrawer(null);
            vportRt.ClearStatus();
            this.commandCtrl.Prompt(string.Empty);

            this.vportRt.CurrentAction = null;
            this.vportRt.CursorType = LcCursorType.SelectElement;
            this.vportRt.CursorAddon = CursorAddonType.None;
            this.vportRt.CommandCenter.InAction = false;
            this.vportRt.CancelCurrentAction();
            if (this.docRt.Action.SelectedElements.Count > 0)
            {
                this.docRt.Action.SetSelectsToDragging(false);
                this.vportRt.ClearElementGrips();
                this.docRt.Action.ClearSelects();
            }
        }
        public virtual void DrawTrans(SKCanvas canvas)    //渲染
        {

            //Vector2 wp =  this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());
            //  //= this.vportRt.HitSelect(this.docRt.Document.ModelSpace, wcsp, wsize);
            //  var hitResult = this.vportRt.HitSelect(this.docRt.Document.ModelSpace, wp, 2);
            if (!this.vportRt.CheckStatus(ViewportStatus.RectSelect))//单个元素的点击状态(如果是单个元素被点击）
            {
                var wcsp = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());//指针移动到的坐标转换为点之后转换为世界坐标
                ////this.inputp = wcsp;
                var wsize = this.vportRt.ConvertScrToWcs(Constants.SelectBoxSize);   //盒子的宽度
                var hitResult = this.vportRt.HitSelect(this.docRt.Document.ModelSpace, wcsp, wsize);
                if (hitResult != null)
                {
                    //  var  inputElement = hitResult.Item1;
                    //if (selectedEXElements.Count > selectedElements.Count)
                    // {
                    if (selectedElements != null)
                    {
                        foreach (var element1 in selectedElements)
                        {
                            if (hitResult.Item1 is LcPolyLine)
                            {
                                DrawAuLcPolyLine(canvas, element1, hitResult.Item1);
                            }
                            else
                            {
                                List<Vector2> points = new List<Vector2>();
                                if(element1 !=null&& hitResult.Item1 != null)
                                {
                                    points = element1.GetCrossVectorByElement(hitResult.Item1);
                                }

                                if (points == null || points.Count == 0)
                                {

                                }
                                else
                                {
                                    if (hitResult.Item1 is LcLine)
                                    {
                                        DrawAuxLine(canvas, points, hitResult.Item1);
                                    }
                                    if (hitResult.Item1 is LcArc)
                                    {
                                        DrawAuArc(canvas, points, hitResult.Item1);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (this.vportRt.CheckStatus(ViewportStatus.RectSelect))//拉取选中状态（如果是被拉取）
            {
                var wcsp1 = this.vportRt.ConvertDcsToWcs(this.vportRt.PointerPressedPosition.ToVector2d()); //指针按下的点坐标转换
                var wcsp2 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());//指针移动到的坐标转换为点之后转换为世界坐标
                ////this.inputp = wcsp;
                var hitResults = this.vportRt.HitSelect(this.docRt.Document.ModelSpace, wcsp1, wcsp2);  //第二次选中的元素格子
                if (hitResults != null)
                {
                    //  var  inputElement = hitResult.Item1;
                    //if (selectedEXElements.Count > selectedElements.Count)
                    // {
                    if (selectedElements != null)
                    {
                        foreach (var element1 in selectedElements)
                        {
                            foreach (var inputElement in hitResults)
                            {
                                if (inputElement is LcPolyLine)
                                {
                                    DrawAuLcPolyLine(canvas, element1, inputElement);
                                }
                                else
                                {
                                    List<Vector2> points = new List<Vector2>();
                                    if(element1 !=null&& inputElement != null)
                                    {
                                        points = element1.GetCrossVectorByElement(inputElement);
                                    }

                                    if (points == null || points.Count == 0)
                                    {
                                        
                                    }
                                    else
                                    {
                                        if (inputElement is LcLine)
                                        {
                                            DrawAuxLine(canvas, points, inputElement);
                                        }
                                        if (inputElement is LcArc)
                                        {
                                            DrawAuArc(canvas, points, inputElement);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

        }
        public void DrawAuxLine(SKCanvas canvas, List<Vector2> points, LcElement element2)
        {
            LcLine line2 = element2 as LcLine;
            Vector2 point = new Vector2();
            SKPaint AuxPen = new SKPaint { Color = SKColors.Gray, IsStroke = true, PathEffect = Constants.SelectedEffect };
            List<Vector2> points2 = points.ToList();
            List<Vector2> point1s = new List<Vector2>();  //point1s用来存储离直线开始点近得点
            List<Vector2> point2s = new List<Vector2>();  //point2s用来存储离直线结束点近得点
            if (points.Count > 0)
            {
                foreach (var item in points)
                {
                    if(item != null)
                    {
                        if (GeoUtils.IsPointOnLineExtension(line2.Start, line2.End, item))
                        {
                        }
                        else
                        {
                            points2.Add(item);
                        }
                    }
                   
                }
                foreach(var item1 in points2)
                {
                    if (item1 != null)
                    {
                        double diatance1 = Vector2.Distance(item1, line2.Start);
                        double diatance2 = Vector2.Distance(item1, line2.End);
                        if (diatance1 < diatance2)
                        {
                            point1s.Add(item1);
                        }
                        else
                        {
                            point2s.Add(item1);
                        }
                    }
                }
            }
            var wcsp1 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());//求出移动点，判断移动点与开始点近还是结束点近
            double diatance3 = Vector2.Distance(wcsp1, line2.Start);
            double diatance4 = Vector2.Distance(wcsp1, line2.End);
            if (diatance3 < diatance4)
            {
                if (point1s.Count == 0)
                {

                }
                else
                {
                    Vector2 temporaryPoint = point1s[0];
                    double temporaryDiantance = Vector2.Distance(point1s[0], line2.Start);
                    foreach (var item in point1s)
                    {
                        double diatance = Vector2.Distance(item, line2.Start);
                        if (diatance < temporaryDiantance)
                        {
                            temporaryDiantance = diatance;
                            temporaryPoint = item;
                        }
                        point = temporaryPoint;
                    }
                    canvas.DrawLine(vportRt.ConvertWcsToScr(point).ToSKPoint(), vportRt.ConvertWcsToScr(line2.End).ToSKPoint(), AuxPen);
                }
            }
            else
            {
                if (point2s.Count == 0)
                {

                }
                else
                {
                    Vector2 temporaryPoint = point2s[0];
                    double temporaryDiantance = Vector2.Distance(point2s[0], line2.End);
                    foreach (var item in point2s)
                    {
                        double diatance = Vector2.Distance(item, line2.End);
                        if (diatance < temporaryDiantance)
                        {
                            temporaryDiantance = diatance;
                            temporaryPoint = item;
                        }
                        point = temporaryPoint;
                    }
                    canvas.DrawLine(vportRt.ConvertWcsToScr(line2.Start).ToSKPoint(), vportRt.ConvertWcsToScr(point).ToSKPoint(), AuxPen);
                }
            }
        }

        //public void DrawAuArc(SKCanvas canvas, LcElement element1, LcElement element2)
        //{
        //    var wcsp1 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());
        //    LcArc lcArc = element2 as LcArc;
        //    List<Vector2> points = element1.GetCrossVectorByLcArc(lcArc);
        //  //指针选中释放的地方
        //    double diatance1 = Vector2.Distance(wcsp1, points[0]);
        //    double diatance2 = Vector2.Distance(wcsp1, points[1]);
        //    Vector2 point = new Vector2();
        //    if (diatance1 < diatance2)
        //    {
        //        point = points[0];
        //    }
        //    else
        //    {
        //        point = points[1];
        //    }
        //    if (point != null)
        //    {
        //        //double diatance1 = Vector2.Distance(point, lcArc.Startp);
        //        //double diatance2 = Vector2.Distance(point, lcArc.Endp);
        //        //判断交点与接触点的距离
        //        double diatance3 = Vector2.Distance(wcsp1, lcArc.Startp);
        //        double diatance4 = Vector2.Distance(wcsp1, lcArc.Endp);
        //        Vector2 end = new Vector2();
        //        Vector2 start = new Vector2();
        //        end = lcArc.Endp;
        //        start = lcArc.Startp;
        //        if (diatance3 > diatance4)
        //        {
        //            end = point;
        //            //lcArc.Endp = point;
        //            //lcArc.Set(end: point);
        //        }
        //        else
        //        {
        //            start = point;
        //            //lcArc.Startp = point;
        //            //lcArc.Set(start: point);
        //        }

        //        lcArc.StartAngle = (Math.Atan2(start.Y - lcArc.Center.Y, start.X - lcArc.Center.X) * 180 / Math.PI);
        //        lcArc.EndAngle = (Math.Atan2(end.Y - lcArc.Center.Y, end.X - lcArc.Center.X) * 180 / Math.PI);
        //        if (lcArc.StartAngle < 0)
        //        {
        //            lcArc.StartAngle += 360;
        //        }
        //        if (lcArc.EndAngle < 0)
        //        {
        //            lcArc.EndAngle += 360;
        //        }
        //        Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
        //        Arc2d arc2D = new Arc2d();  //逻辑模型
        //        arc2D.IsClockwise = false;
        //        arc2D.StartAngle = lcArc.StartAngle * Math.PI / 180;
        //        arc2D.EndAngle = lcArc.EndAngle * Math.PI / 180;
        //        arc2D.Center = lcArc.Center;
        //        arc2D.Radius = lcArc.Radius;



        //        this.vportRt.DrawArc(arc2D, matrix, canvas, Constants.auxElementPen);
        //    }



        //    //Vector2 point = element1.GetCrossVectorByLcArc(lcArc);


        //    //if (point != null)
        //    //{
        //    //    double diatance1 = Vector2.Distance(point, lcArc.Startp);
        //    //    double diatance2 = Vector2.Distance(point, lcArc.Endp);
        //    //    if (diatance1 > diatance2)
        //    //    {
        //    //        lcArc.Endp = point;
        //    //    }
        //    //    else
        //    //    {
        //    //        lcArc.Startp = point;
        //    //    }
        //    //        Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
        //    //    Arc2d arc2D = new Arc2d();  //逻辑模型
        //    //    arc2D.IsClockwise = false;
        //    //    arc2D.StartAngle = lcArc.StartAngle;
        //    //    arc2D.EndAngle = lcArc.EndAngle;
        //    //    arc2D.Center = lcArc.Center;
        //    //    arc2D.Radius = lcArc.Radius;
        //    //    this.vportRt.DrawArc(arc2D, matrix, canvas, Constants.auxElementPen);
        //    //}
        //}

        public void DrawAuArc(SKCanvas canvas, List<Vector2> points, LcElement element2)
        {
            Vector2 point = new Vector2();
            LcArc lcArc = element2 as LcArc;
            Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
            Arc2d arc2D = new Arc2d();  //逻辑模型
            arc2D.IsClockwise = false;
            List<Vector2> point1s = new List<Vector2>();  //point1s用来存储离直线开始点近得点
            List<Vector2> point2s = new List<Vector2>();  //point2s用来存储离直线结束点近得点
            bool rf;
            if (points.Count > 0)
            {
                List<Vector2> endpoints = new List<Vector2>();
                foreach (var item in points)
                {
                    if(item != null)
                    {

                        //&& GeoUtils.IsPointOnArcExtension(arc2D, item)
                        if (!Arc2d.PointInArc(item, lcArc.Startp, lcArc.Endp, lcArc.Center))
                        {
                            endpoints.Add(item);
                        }
                    }

                }
                foreach (var item in endpoints)
                {
                    if (endpoints.Count == 1)
                    {
                        point1s.Add(item);
                        point2s.Add(item);
                    }
                    else
                    {
                        double distance1 = Vector2.Distance(item, lcArc.Startp);
                        double distance2 = Vector2.Distance(item, lcArc.Endp);
                        if (distance1 < distance2)
                        {
                            point1s.Add(item);
                        }
                        else
                        {
                            point2s.Add(item);
                        }
                    }
                }
            }
            var wcsp1 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());
            double ds = Vector2.Distance(wcsp1, lcArc.Startp);
            double de = Vector2.Distance(wcsp1, lcArc.Endp);
            if (ds < de)
            {
                if (point1s.Count == 0)
                {
                    return;
                }
                else
                {
                    Vector2 temporaryPoint = point1s[0];
                    double temporaryDiantance = Vector2.Distance(point1s[0], lcArc.Startp);
                    foreach (var item in point1s)
                    {
                        double diatance = Vector2.Distance(item, lcArc.Startp);
                        if (diatance < temporaryDiantance)
                        {
                            temporaryDiantance = diatance;
                            temporaryPoint = item;
                        }
                        point = temporaryPoint;

                    }
                    //lcArc.Set(start: point);
                    arc2D = Arc2d.CreatePCE(point, lcArc.Center, lcArc.Endp);
                    //arc2D = ArcAction.GetARC(point, ArcAction.Getmidpoint(lcArc.StartAngle, lcArc.EndAngle, lcArc.Center, lcArc.Startp), lcArc.Endp, out rf);
                }
            }
            else
            {
                if (point2s.Count == 0)
                {
                    return;
                }
                else
                {
                    Vector2 temporaryPoint = point2s[0];
                    double temporaryDiantance = Vector2.Distance(point2s[0], lcArc.Endp);
                    foreach (var item in point2s)
                    {
                        double diatance = Vector2.Distance(item, lcArc.Endp);
                        if (diatance < temporaryDiantance)
                        {
                            temporaryDiantance = diatance;
                            temporaryPoint = item;
                        }
                        point = temporaryPoint;

                    }
                    arc2D = Arc2d.CreatePCE(lcArc.Startp, lcArc.Center, point);
                    //arc2D = ArcAction.GetARC(lcArc.Startp, ArcAction.Getmidpoint(lcArc.StartAngle, lcArc.EndAngle, lcArc.Center, lcArc.Startp), point, out rf);
                    //lcArc.Set(end: point);
                }
            }
            this.vportRt.DrawArc(arc2D, matrix, canvas, Constants.auxElementPen);
        }

        public void DrawAuLcPolyLine(SKCanvas canvas, LcElement element1, LcElement element2)
        {
            List<Vector2> points = new List<Vector2>();
            var wcsp1 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());
            LcPolyLine lcPolyLine = (LcPolyLine)element2;
            //判断多段线是第一段改还是最后一段改
            double ds = Vector2.Distance(wcsp1, LcPolyLine.GetStart(lcPolyLine.Curve2ds[0]));
            double de = Vector2.Distance(wcsp1, LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()));
            List<Vector2> points1 = new List<Vector2>();
            SKPaint AuxPen = new SKPaint { Color = SKColors.Gray, IsStroke = true, PathEffect = Constants.SelectedEffect };
            //多段线的第一段改
            if (ds < de)
            {
                var element = lcPolyLine.Curve2ds[0];
                //判段多段线第一段是线
                if (element is Line2d)
                {
                    points1 = element1.GetCrossVectorByLine(element as Line2d);
                    Vector2 point = new Vector2();
                    if (points1.Count == 1)
                    {
                        point = points1[0];
                    }
                    if (points1.Count == 2)  //如果交点有两个
                    {
                        double diatance1 = Vector2.Distance(points1[0], wcsp1);
                        double diatance2 = Vector2.Distance(points1[1], wcsp1);
                        if (diatance1 < diatance2)
                        {
                            point = points1[0];
                        }
                        else { point = points1[1]; }
                    }
                    if (point != null && points1.Count != 0)
                    {
                        if (GeoUtils.IsPointOnLineExtension(LcPolyLine.GetStart(lcPolyLine.Curve2ds[0]), LcPolyLine.GetEnd(lcPolyLine.Curve2ds[0]), point)==false )
                        {
                            double distance3 = Vector2.Distance(point, LcPolyLine.GetEnd(lcPolyLine.Curve2ds[0]));
                            double distance4 = Vector2.Distance(point, LcPolyLine.GetStart(lcPolyLine.Curve2ds[0]));
                            if (distance3 > distance4)
                            {
                                canvas.DrawLine(vportRt.ConvertWcsToScr((lcPolyLine.Curve2ds[0] as Line2d).Start).ToSKPoint(), vportRt.ConvertWcsToScr(point).ToSKPoint(), AuxPen);
                                //(lcPolyLine.Curve2ds.Last() as Line2d).End = point;
                            }
                        }
                    }
                }
                else   //多段线的第一段是弧
                {
                    Arc2d arc = element as Arc2d;
                    points1 = element1.GetCrossVectorByArc(element as Arc2d);
                    Vector2 point = new Vector2();
                    Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                    Arc2d arc2D = new Arc2d();  //逻辑模型
                    arc2D.IsClockwise = false;
                    List<Vector2> points2 = new List<Vector2>();
                    foreach (var item in points1)
                    {
                        if (!Arc2d.PointInArc(item, (lcPolyLine.Curve2ds[0] as Arc2d).Startp, (lcPolyLine.Curve2ds[0] as Arc2d).Endp, (lcPolyLine.Curve2ds[0] as Arc2d).Center)) //判断点是否在圆弧上
                        {
                            points2.Add(item);
                        }
                    }
                    if (points2.Count == 0)
                    { return; }
                    if (points2.Count == 1)
                    {
                        point = points2[0];
                    }
                    if (points2.Count == 2)
                    {
                        double diatance1 = Vector2.Distance((lcPolyLine.Curve2ds[0] as Arc2d).Startp, points2[0]);
                        double diatance2 = Vector2.Distance((lcPolyLine.Curve2ds[0] as Arc2d).Startp, points2[1]);
                        if (diatance1 < diatance2)
                        {
                            point = points2[0];
                        }
                        else
                        {
                            point = points2[1];
                        }
                    }
                    if (point != null && points2.Count != 0)
                    {
                        arc2D = Arc2d.CreatePCE(point, arc.Center, arc.Endp);
                        //arc = Arc2d.CreatePCE(point, arc.Center, arc.Endp);
                        //lcPolyLine.Curve2ds[0] = arc;
                    }
                    this.vportRt.DrawArc(arc2D, matrix, canvas, Constants.auxElementPen);
                }
            }
            //多段线的最后一段改
            else
            {
                var element = lcPolyLine.Curve2ds.Last();
                //最后一段是线
                if (element is Line2d)
                {
                    points1 = element1.GetCrossVectorByLine(element as Line2d);
                    Vector2 point = new Vector2();
                    if (points1.Count == 1)
                    {
                        point = points1[0];
                    }
                    if (points1.Count == 2)  //如果交点有两个
                    {
                        double diatance1 = Vector2.Distance(points1[0], wcsp1);
                        double diatance2 = Vector2.Distance(points1[1], wcsp1);
                        if (diatance1 < diatance2)
                        {
                            point = points1[0];
                        }
                        else { point = points1[1]; }
                    }
                    if (point != null && points1.Count != 0)
                    {
                        //bool isOnLineExtension = GeoUtils.IsPointOnLineExtension(LcPolyLine.GetStart(lcPolyLine.Curve2ds.Last()), LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()), point);
                        if (GeoUtils.IsPointOnLineExtension(LcPolyLine.GetStart(lcPolyLine.Curve2ds.Last()), LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()), point)==false)
                        {
                            double distance3 = Vector2.Distance(point, LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()));
                            double distance4 = Vector2.Distance(point, LcPolyLine.GetStart(lcPolyLine.Curve2ds.Last()));
                            if (distance3 < distance4)
                            {
                                canvas.DrawLine(vportRt.ConvertWcsToScr((lcPolyLine.Curve2ds.Last() as Line2d).End).ToSKPoint(), vportRt.ConvertWcsToScr(point).ToSKPoint(), AuxPen);
                                //(lcPolyLine.Curve2ds.Last() as Line2d).End = point;
                            }
                        }
                    }
                }
                //多段线的最后一段是弧
                else
                {
                    Arc2d arc = element as Arc2d;
                    points1 = element1.GetCrossVectorByArc(element as Arc2d);
                    Vector2 point = new Vector2();
                    Arc2d arc2D = new Arc2d();  //逻辑模型
                    Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                    arc2D.IsClockwise = false;
                    List<Vector2> points2 = new List<Vector2>();
                    foreach (var item in points1)
                    {
                        if (!Arc2d.PointInArc(item, (lcPolyLine.Curve2ds.Last() as Arc2d).Startp, (lcPolyLine.Curve2ds.Last() as Arc2d).Endp, (lcPolyLine.Curve2ds.Last() as Arc2d).Center)) //判断点是否在圆弧上
                        {
                            points2.Add(item);
                        }
                    }
                    if (points2.Count == 0)
                    { return; }
                    if (points2.Count == 1)
                    {
                        point = points2[0];
                    }
                    if (points2.Count == 2)
                    {
                        double diatance1 = Vector2.Distance((lcPolyLine.Curve2ds.Last() as Arc2d).Endp, points2[0]);
                        double diatance2 = Vector2.Distance((lcPolyLine.Curve2ds.Last() as Arc2d).Endp, points2[1]);
                        if (diatance1 < diatance2)
                        {
                            point = points2[0];
                        }
                        else
                        {
                            point = points2[1];
                        }
                    }
                    if (point != null && points2.Count != 0)
                    {
                        arc2D = Arc2d.CreatePCE(arc.Startp, arc.Center, point);
                    }
                    this.vportRt.DrawArc(arc2D, matrix, canvas, Constants.auxElementPen);
                }
            }
        }
        protected void DetachEvents()
        {
            //    vportRt.Control.DetachEvents(this.OnViewportMouseEvent, this.OnViewportKeyDown);
            //docRt.Commander.DetachInputEvent(OnInputKeyDown, OnInputKeyUp);
        }
        public void ExtendPolyLine(LcElement element1, LcElement element2, List<Vector2> points)
        {
            var wcsp1 = this.vportRt.ConvertScrToWcs(this.vportRt.PointerMovedPosition.ToVector2d());
            LcPolyLine lcPolyLine = (LcPolyLine)element2;
            //判断多段线是第一段改还是最后一段改
            double ds = Vector2.Distance(wcsp1, LcPolyLine.GetStart(lcPolyLine.Curve2ds[0]));
            double de = Vector2.Distance(wcsp1, LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()));
            List<Vector2> points1 = new List<Vector2>();
            //多段线的第一段改
            if (ds < de)
            {
                var element = lcPolyLine.Curve2ds[0];
                //判段多段线第一段是线
                if (element is Line2d)
                {
                    points1 = element1.GetCrossVectorByLine(element as Line2d);
                    Vector2 point = new Vector2();
                    if (points1.Count == 1)
                    {
                        point = points1[0];
                    }
                    if (points1.Count == 2)  //如果交点有两个
                    {
                        double diatance1 = Vector2.Distance(points1[0], wcsp1);
                        double diatance2 = Vector2.Distance(points1[1], wcsp1);
                        if (diatance1 < diatance2)
                        {
                            point = points1[0];
                        }
                        else { point = points1[1]; }
                    }
                    if (point != null && points1.Count != 0)
                    {
                        //bool isOnLineExtension = GeoUtils.IsPointOnLineExtension(LcPolyLine.GetStart(lcPolyLine.Curve2ds[0]), LcPolyLine.GetEnd(lcPolyLine.Curve2ds[0]), point);
                        if (GeoUtils.IsPointOnLineExtension(LcPolyLine.GetStart(lcPolyLine.Curve2ds[0]), LcPolyLine.GetEnd(lcPolyLine.Curve2ds[0]), point)==false)
                        {
                            double distance3 = Vector2.Distance(point, LcPolyLine.GetEnd(lcPolyLine.Curve2ds[0]));
                            double distance4 = Vector2.Distance(point, LcPolyLine.GetStart(lcPolyLine.Curve2ds[0]));
                            if (distance4 < distance3)
                            {
                                (lcPolyLine.Curve2ds[0] as Line2d).Start = point;
                            }
                        }
                    }
                }
                else   //多段线的第一段是弧
                {
                    Arc2d arc = element as Arc2d;
                    points1 = element1.GetCrossVectorByArc(element as Arc2d);
                    Vector2 point = new Vector2();
                    Arc2d arc2D = new Arc2d();  //逻辑模型
                    arc2D.IsClockwise = false;
                    List<Vector2> points2 = new List<Vector2>();
                    foreach (var item in points1)
                    {
                        if (!Arc2d.PointInArc(item, (lcPolyLine.Curve2ds[0] as Arc2d).Startp, (lcPolyLine.Curve2ds[0] as Arc2d).Endp, (lcPolyLine.Curve2ds[0] as Arc2d).Center)) //判断点是否在圆弧上
                        {
                            points2.Add(item);
                        }
                    }
                    if (points2.Count == 0)
                    { return; }
                    if (points2.Count == 1)
                    {
                        point = points2[0];
                    }
                    if (points2.Count == 2)
                    {
                        double diatance1 = Vector2.Distance((lcPolyLine.Curve2ds[0] as Arc2d).Startp, points2[0]);
                        double diatance2 = Vector2.Distance((lcPolyLine.Curve2ds[0] as Arc2d).Startp, points2[1]);
                        if (diatance1 < diatance2)
                        {
                            point = points2[0];
                        }
                        else
                        {
                            point = points2[1];
                        }
                    }
                    if (point != null && points2.Count != 0)
                    {
                        arc = Arc2d.CreatePCE(point, arc.Center, arc.Endp);
                        lcPolyLine.Curve2ds[0] = arc;
                    }
                }
            }
            //多段线的最后一段改
            else
            {
                var element = lcPolyLine.Curve2ds.Last();
                //最后一段是线
                if (element is Line2d)
                {
                    points1 = element1.GetCrossVectorByLine(element as Line2d);
                    Vector2 point = new Vector2();
                    if (points1.Count == 1)
                    {
                        point = points1[0];
                    }
                    if (points1.Count == 2)  //如果交点有两个
                    {
                        double diatance1 = Vector2.Distance(points1[0], wcsp1);
                        double diatance2 = Vector2.Distance(points1[1], wcsp1);
                        if (diatance1 < diatance2)
                        {
                            point = points1[0];
                        }
                        else { point = points1[1]; }
                    }
                    if (point != null && points1.Count != 0)
                    {
                        //bool isOnLineExtension = GeoUtils.IsPointOnLineExtension(LcPolyLine.GetStart(lcPolyLine.Curve2ds.Last()), LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()), point);
                        if (GeoUtils.IsPointOnLineExtension(LcPolyLine.GetStart(lcPolyLine.Curve2ds.Last()), LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()), point)==false)
                        {
                            double distance3 = Vector2.Distance(point, LcPolyLine.GetEnd(lcPolyLine.Curve2ds.Last()));
                            double distance4 = Vector2.Distance(point, LcPolyLine.GetStart(lcPolyLine.Curve2ds.Last()));
                            if (distance3 < distance4)
                            {
                                (lcPolyLine.Curve2ds.Last() as Line2d).End = point;
                            }
                        }
                    }
                }
                //多段线的最后一段是弧
                else
                {
                    Arc2d arc = element as Arc2d;
                    points1 = element1.GetCrossVectorByArc(element as Arc2d);
                    Vector2 point = new Vector2();
                    Arc2d arc2D = new Arc2d();  //逻辑模型
                    arc2D.IsClockwise = false;
                    List<Vector2> points2 = new List<Vector2>();
                    foreach (var item in points1)
                    {
                        if (!Arc2d.PointInArc(item, (lcPolyLine.Curve2ds.Last() as Arc2d).Startp, (lcPolyLine.Curve2ds.Last() as Arc2d).Endp, (lcPolyLine.Curve2ds.Last() as Arc2d).Center)) //判断点是否在圆弧上
                        {
                            points2.Add(item);
                        }
                    }
                    if (points2.Count == 0)
                    { return; }
                    if (points2.Count == 1)
                    {
                        point = points2[0];
                    }
                    if (points2.Count == 2)
                    {
                        double diatance1 = Vector2.Distance((lcPolyLine.Curve2ds.Last() as Arc2d).Endp, points2[0]);
                        double diatance2 = Vector2.Distance((lcPolyLine.Curve2ds.Last() as Arc2d).Endp, points2[1]);
                        if (diatance1 < diatance2)
                        {
                            point = points2[0];
                        }
                        else
                        {
                            point = points2[1];
                        }
                    }
                    if (point != null && points2.Count != 0)
                    {
                        arc = Arc2d.CreatePCE(arc.Startp, arc.Center, point);
                        lcPolyLine.Curve2ds[lcPolyLine.Curve2ds.Count - 1] = arc;
                    }
                }
            }

        }
    }
}

